/*
 * @Author: zhengzhuang
 * @Date: 2021-01-15 14:06:41
 * @LastEditors: zhengzhuang
 * @LastEditTime: 2021-01-16 10:55:20
 * @Description: 单独请求服务 SeparateRequestService
 * @FilePath: /C20Driver/lib/service/separate_request_service.dart
 */
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:C20Driver/config/service_api.dart';
import 'package:C20Driver/model/base_entity.dart';
import 'package:C20Driver/model/base_list_entity.dart';
import 'package:C20Driver/model/error_entity.dart';
import 'package:C20Driver/resources/app_storage_interface.dart';
import 'package:C20Driver/routers/navigator_util.dart';
import 'package:C20Driver/utils/toast.dart';
import 'package:package_info/package_info.dart';
import 'package:shared_preferences/shared_preferences.dart';

enum ReqMethod { GET, POST, DELETE, PUT }

/// 使用：ReqMethodValues[ReqMethod.POST]
const ReqMethodValues = {
  ReqMethod.GET: "get",
  ReqMethod.POST: "post",
  ReqMethod.DELETE: "delete",
  ReqMethod.PUT: "put"
};

class SeparateRequestService {
  static final SeparateRequestService _shared =
      SeparateRequestService._internal();
  BaseOptions options;
  BuildContext context;
  factory SeparateRequestService() => _shared;
  Dio dio;
  SeparateRequestService._internal() {
    if (dio == null) {
      options = BaseOptions(
          // baseUrl: "http://root.maitianshanglv.com/api",
          contentType: Headers.jsonContentType,
          responseType: ResponseType.json,
          receiveDataWhenStatusError: false,
          connectTimeout: 30000,
          receiveTimeout: 30000,
          headers: ServiceApi.httpHeaders);
      dio = Dio(options);
    }
  }

  /// 获取Token
  static Future<String> getToken() async {
    // loginToken为空 从本地存储获取
    String _token = '';
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _token = prefs.getString(AppStorageInterface.LOGINTOKEN); // 存储token到本地
    // print('缓存获取到的Token*********************${_token}');
    return _token;
  }

  // 请求，返回参数为 T
  // method：请求方法，NWMethod.POST等
  // path：请求地址
  // params：请求参数
  // success：请求成功回调
  // error：请求失败回调
  Future request<T>(ReqMethod method, String path,
      {Map<String, dynamic> params,
      // Function(T) success,
      Function(ErrorEntity) failed}) async {
    try {
      String _loginToken = await getToken();
      PackageInfo packageInfo = await PackageInfo.fromPlatform();
      String _currentVersionCode = packageInfo.version;
      if (params == null) {
        params = {'token': _loginToken, 'version': _currentVersionCode};
      } else {
        params['token'] = _loginToken;
        params['version'] = _currentVersionCode;
      }
      Response response = await dio.request(path,
          data: params,
          // queryParameters: params,
          options: Options(method: ReqMethodValues[method]));
      // print('++++++结果+++++++++url==' + path);
      // print(response);
      // if (response != null) {
      //   // if(response) {}
      //   // BaseEntity entity = BaseEntity<T>.fromJson(response.data);
      //   // print(response);
      //   // if (entity.ret == 200) {
      //   //   if (entity.code == '0000') {
      //   //     return success(entity.data);
      //   //   } else if (entity.code == '6100' || entity.code == '6200' || entity.code == '6300') {
      //   //     // token过期
      //   //     NavigatorUtil.goToLoginRemovePage();
      //   //   } else {
      //   //     ToastX.center(entity.message);
      //   //     failed(ErrorEntity(code: int.parse(entity.code), message: entity.message));
      //   //   }
      //   // } else {
      //   //   ToastX.center(entity.message);
      //   //   failed(ErrorEntity(code: int.parse(entity.code), message: entity.message));
      //   // }
      // } else {
      //   failed(ErrorEntity(code: -1, message: "未知错误"));
      // }
    } on DioError catch (e) {
      print('后台请求报错=======>$e');
      print(createErrorEntity(e));
      // error(createErrorEntity(e));
    }
  }

  // 请求，返回参数为 List<T>
  // method：请求方法，NWMethod.POST等
  // path：请求地址
  // params：请求参数
  // success：请求成功回调
  // error：请求失败回调
  Future requestList<T>(ReqMethod method, String path,
      {Map<String, dynamic> params,
      Function(List<T>) success,
      Function(ErrorEntity) failed}) async {
    try {
      print(ServiceApi.baseApi + path);
      String _loginToken = await getToken();
      PackageInfo packageInfo = await PackageInfo.fromPlatform();
      String _currentVersionCode = packageInfo.version;
      if (params == null) {
        params = {'token': _loginToken, 'version': _currentVersionCode};
      } else {
        params['token'] = _loginToken;
        params['version'] = _currentVersionCode;
      }
      // print('请求数据：==============$params');
      Response response = await dio.request(path,
          queryParameters: params,
          options: Options(method: ReqMethodValues[method]));
      print(response);
      if (response != null) {
        BaseListEntity entity = BaseListEntity<T>.fromJson(response.data);
        if (entity.ret == 200) {
          if (entity.code == '0000') {
            return success(entity.data);
          } else {
            return ToastX.center(entity.message);
          }
        } else {
          return failed(ErrorEntity(
              code: int.parse(entity.code), message: entity.message));
        }
      } else {
        return failed(ErrorEntity(code: -1, message: "未知错误"));
      }
    } on DioError catch (e) {
      return failed(createErrorEntity(e));
    }
  }

  // 文件上传
  // 请求，返回参数为 T
  // method：请求方法，NWMethod.POST等
  // path：请求地址
  // params：请求参数
  // success：请求成功回调
  // error：请求失败回调
  Future uploadFile<T>(ReqMethod method, String path,
      {Map<String, dynamic> params,
      Function(T) success,
      Function(ErrorEntity) failed}) async {
    try {
      print(ServiceApi.baseApi + path);
      String _loginToken = await getToken();
      PackageInfo packageInfo = await PackageInfo.fromPlatform();
      String _currentVersionCode = packageInfo.version;
      if (params == null) {
        params = {'token': _loginToken, 'version': _currentVersionCode};
      } else {
        params['token'] = _loginToken;
        params['version'] = _currentVersionCode;
      }
      var imgPath = params['file'];
      print(imgPath);
      String imgName =
          imgPath.substring(imgPath.lastIndexOf("/") + 1, imgPath.length);
      FormData formdata = FormData.fromMap({
        "file": await MultipartFile.fromFile(
          params['file'], //图片路径
          filename: imgName, //图片名称
        )
      });

      Response response = await dio.request(
        path,
        data: formdata,
        queryParameters: params,
        options: Options(method: ReqMethodValues[method]),
        onSendProgress: (int count, int total) {
          print('-----------上传进度${count / total}-------------'); //上传进度
        },
      );
      if (response != null) {
        BaseEntity entity = BaseEntity<T>.fromJson(response.data);
        if (entity.ret == 200) {
          if (entity.code == '0000') {
            return success(entity.data);
          } else {
            ToastX.center(entity.message);
          }
        } else {
          failed(ErrorEntity(
              code: int.parse(entity.code), message: entity.message));
        }
      } else {
        failed(ErrorEntity(code: -1, message: "未知错误"));
      }
      return '';
    } on DioError catch (e) {
      print('后台请求报错=======>$e');
      // print(createErrorEntity(e));
      // failed(createErrorEntity(e));
    }
  }

  /* *
   * App软件升级
   */
  Future requestAppUpdata({formData}) async {
    try {
      Response response;
      Dio dio = new Dio();
      response = await dio.post(
          'http://appstore.maitianshanglv.com/?service=AppUpdate.GetVersionMessage',
          data: formData,
          queryParameters: formData);
      if (response.statusCode == 200) {
        var jsonData = json.decode(response.toString())['data'];
        return jsonData;
      } else {
        throw Exception('后端接口出现异常，请检查代码和服务器状况......');
      }
    } catch (e) {
      return print('ERROR(错误):======>$e');
    }
  }

  // 错误信息
  ErrorEntity createErrorEntity(DioError error) {
    switch (error.type) {
      case DioErrorType.CANCEL:
        {
          return ErrorEntity(code: -1, message: "请求取消");
        }
        break;
      case DioErrorType.CONNECT_TIMEOUT:
        {
          return ErrorEntity(code: -1, message: "连接超时");
        }
        break;
      case DioErrorType.SEND_TIMEOUT:
        {
          return ErrorEntity(code: -1, message: "请求超时");
        }
        break;
      case DioErrorType.RECEIVE_TIMEOUT:
        {
          return ErrorEntity(code: -1, message: "响应超时");
        }
        break;
      case DioErrorType.RESPONSE:
        {
          try {
            int errCode = error.response.statusCode;
            String errMsg = error.response.statusMessage;
            print(errCode);
            print(errMsg);
            return ErrorEntity(code: -1, message: "未知错误");
            // return '1';
            // return ErrorEntity(code: "$errCode", message: errMsg);
//          switch (errCode) {
//            case 400: {
//              return ErrorEntity(code: errCode, message: "请求语法错误");
//            }
//            break;
//            case 403: {
//              return ErrorEntity(code: errCode, message: "服务器拒绝执行");
//            }
//            break;
//            case 404: {
//              return ErrorEntity(code: errCode, message: "无法连接服务器");
//            }
//            break;
//            case 405: {
//              return ErrorEntity(code: errCode, message: "请求方法被禁止");
//            }
//            break;
//            case 500: {
//              return ErrorEntity(code: errCode, message: "服务器内部错误");
//            }
//            break;
//            case 502: {
//              return ErrorEntity(code: errCode, message: "无效的请求");
//            }
//            break;
//            case 503: {
//              return ErrorEntity(code: errCode, message: "服务器挂了");
//            }
//            break;
//            case 505: {
//              return ErrorEntity(code: errCode, message: "不支持HTTP协议请求");
//            }
//            break;
//            default: {
//              return ErrorEntity(code: errCode, message: "未知错误");
//            }
//          }
          } on Exception catch (_) {
            return ErrorEntity(code: -1, message: "未知错误");
          }
        }
        break;
      default:
        {
          return ErrorEntity(code: -1, message: error.message);
        }
    }
  }
}
